// Attribute.h: interface for the CAttribute class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_ATTRIBUTE_H__8781445B_8632_45E0_A774_CC1858F14701__INCLUDED_)
#define AFX_ATTRIBUTE_H__8781445B_8632_45E0_A774_CC1858F14701__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#ifdef IPV6_SUPPORT
#ifdef WIN32
	#include "winsock2.h"
	#include "ws2tcpip.h"
#else
	#include <sys/types.h>
	#include <sys/socket.h>
	#include <netdb.h>
#endif
	#include "stdio.h"
	#include "stdlib.h"
#endif

#include "osplatform.h"

#include <string.h>
//****************** RFC3489 *************************
///
//					rfc3489
//
//****************************************************

/// define a structure to hold a stun address 
const unsigned char  IPv4Family = 0x01;
const unsigned char  IPv6Family = 0x02;

// define  flags  
const unsigned long ChangeIpFlag   = 0x04;
const unsigned long ChangePortFlag = 0x02;

#define STUN_ATTRIBUTE_MAPPED_ADDRESS		0x0001 
#define STUN_ATTRIBUTE_RESPONSE_ADDRESS		0x0002
#define STUN_ATTRIBUTE_CHANGE_REQUEST		0x0003
#define STUN_ATTRIBUTE_SOURCE_ADDRESS		0x0004
#define STUN_ATTRIBUTE_CHANGED_ADDRESS		0x0005
#define STUN_ATTRIBUTE_USERNAME				0x0006
#define STUN_ATTRIBUTE_PASSWORD				0x0007
#define STUN_ATTRIBUTE_MESSAGE_INTEGRITY	0x0008
#define STUN_ATTRIBUTE_ERROR_CODE			0x0009
#define STUN_ATTRIBUTE_UNKNOWN_ATTRIBUTES	0x000a
#define STUN_ATTRIBUTE_REFLECTED_FROM		0x000b

#define TURN_ATTRIBUTE_LIFETIME				0x000d
#define TURN_ATTRIBUTE_ALTERNATE_SERVER		0x000e
#define TURN_ATTRIBUTE_MAGIC_COOKIE			0x000f
#define TURN_ATTRIBUTE_BANDWIDTH			0x0010
#define TURN_ATTRIBUTE_DESTINATION_ADDRESS	0x0011
#define TURN_ATTRIBUTE_SOURCE_ADDRESS		0x0012
#define TURN_ATTRIBUTE_DATA					0x0013
#define TURN_ATTRIBUTE_NONCE				0x0014
#define TURN_ATTRIBUTE_REALM				0x0015
#define TURN_ATTRIBUTE_CHANNEL_ID			0x0016
#define TURN_ATTRIBUTE_VIDEO_WIDTH			0x0017
#define TURN_ATTRIBUTE_VIDEO_HEIGHT			0x0018
#define TURN_ATTRIBUTE_VIDEO_FORMAT			0x0019
#define TURN_ATTRIBUTE_VIDEO_FRAMERATE		0x001a
#define TURN_ATTRIBUTE_RECORD_ID			0x001b
#define TURN_ATTRIBUTE_OWNER_ID				0x001c
#define TURN_ATTRIBUTE_SUBTITLE_POS			0x001d
#define TURN_ATTRIBUTE_TIMETITLE_POS		0x001e
#define TURN_ATTRIBUTE_SUBTITLE				0x001f
#define TURN_ATTRIBUTE_START_TIME			0x002f
#define TURN_ATTRIBUTE_STOP_TIME			0x003f
#define TURN_ATTRIBUTE_PLAY_SCALE			0x004f
#define TURN_ATTRIBUTE_PLAY_TYPE			0x005f

//add for media server
#define MS_ATTRIBUTE_PROTO_TYPE				0x0100//tcp - 1;udp - 2;rtp - 3
#define MS_ATTRIBUTE_RECV_CHANNEL_ID		0x0101//recv channel id
#define MS_ATTRIBUTE_TRANSMIT_CHANNEL_ID	0x0102//transmit channel id
#define MS_ATTRIBUTE_ADDRESS				0x0103//allocated recv channel's address
#define MS_ATTRIBUTE_SOURCE_ADDRESS			0x0104
#define MS_ATTRIBUTE_DESTINATION_ADDRESS	0x0105
#define MS_ATTRIBUTE_SESSION_ID				0x0106


//////////////////////////////////////////////////////////////////////////
// The following commands are added by Stone Whoo @20070128
//////////////////////////////////////////////////////////////////////////
#define MS_ATTRIBUTE_USERNAME_ENCRYPTED		0x0107	// user name with encrypted data
#define MS_ATTRIBUTE_PASSWORD_ENCRYPTED		0x0108	// user password with encrypted data

#define MS_ATTRIBUTE_KEEPALIVE_VALUE		0x0109
#define MS_ATTRIBUTE_ERROR_CODE				0x010A

#define MS_ATTRIBUTE_RECV_PORT_ID			0x010B
#define MS_ATTRIBUTE_TRANSMIT_PORT_ID		0x010C
#define MS_ATTRIBUTE_RELAY_CHANNEL_ID		0x010D

#define MS_ATTRIBUTE_RECV_CHANNEL   		0x010E
#define MS_ATTRIBUTE_RELAY_CHANNEL		    0x010F
#define MS_ATTRIBUTE_RELAY_SERVER_ID		0x0110
#define MS_ATTRIBUTE_MAX_CONNN_NUM			0x0111
//////////////////////////////////////////////////////////////////////////
// The above commands are added by Stone Whoo @20070128
//////////////////////////////////////////////////////////////////////////



/*
	Message Attributes
	0x0001: MAPPED-ADDRESS
	0x0002: RESPONSE-ADDRESS
	0x0003: CHANGE-REQUEST
	0x0004: SOURCE-ADDRESS
	0x0005: CHANGED-ADDRESS
	0x0006: USERNAME
	0x0007: PASSWORD
	0x0008: MESSAGE-INTEGRITY
	0x0009: ERROR-CODE
	0x000a: UNKNOWN-ATTRIBUTES
	0x000b: REFLECTED-FROM
*/

class CAttribute  
{
public:
	CAttribute();
	virtual ~CAttribute();
protected:
	unsigned short	m_nType;
	unsigned short	m_nLength;
};

class CMappedAddress:public CAttribute{//	0x0001: MAPPED-ADDRESS
public:
	CMappedAddress();
	CMappedAddress(int family,unsigned long ipv4,unsigned short port);
#ifdef IPV6_SUPPORT
	CMappedAddress(int family,struct in6_addr & ipv6,unsigned short port);	
#endif
	virtual ~CMappedAddress();

	void SetFamily(unsigned char family){m_Family = family;};
	void SetPort(unsigned short port){m_nPort = port;};
	void SetIPV4(unsigned long ip){m_IPV4 = ip;};
	unsigned char GetFamily(){return m_Family;};
	unsigned short GetPort()const {return m_nPort;};
	unsigned long GetIPV4()const {return m_IPV4;};
	int  Encode(unsigned char *pdata,int len);
	int	Decode(unsigned char *pdata,int len);
#ifdef IPV6_SUPPORT
/* suggest use string better */
	struct in6_addr m_ipv6;
	struct in6_addr GetIPv6()const{return m_ipv6;};
#endif

protected:
	unsigned char	m_XX;
	unsigned char	m_Family;
	unsigned short	m_nPort;
	unsigned long	m_IPV4;
};
class CResponseAddress:public CAttribute{//0x0002: RESPONSE-ADDRESS
public:
	CResponseAddress();
	virtual ~CResponseAddress();

	void SetFamily(unsigned char family){m_Family = family;};
	void SetPort(unsigned short port){m_nPort = port;};
	void SetIPV4(unsigned long ip){m_IPV4 = ip;};
	unsigned char GetFamily()const{return m_Family;};
	unsigned short GetPort()const{return m_nPort;};
	unsigned long GetIPV4()const{return m_IPV4;};
	int  Encode(unsigned char *pdata,int len);
	int	Decode(unsigned char *pdata,int len);
private:
	unsigned char	m_XX;
	unsigned char	m_Family;
	unsigned short	m_nPort;
	unsigned long	m_IPV4;
};

class CRecvChannel:public CAttribute{//	0x0001: MAPPED-ADDRESS
public:
	CRecvChannel();
	CRecvChannel(int proto,int family,unsigned long ipv4,unsigned short port,unsigned long chid);
	virtual ~CRecvChannel();
	void SetProto(unsigned char proto){m_XX = proto;};

	void SetFamily(unsigned char family){m_Family = family;};
	void SetPort(unsigned short port){m_nPort = port;};
	void SetIPV4(unsigned long ip){m_IPV4 = ip;};
	void SetChannelID(unsigned long id){m_nChannelID = id;};
	unsigned char GetProto()const{return m_XX;};
	unsigned char GetFamily()const{return m_Family;};
	unsigned short GetPort()const {return m_nPort;};
	unsigned long GetIPV4()const {return m_IPV4;};
	unsigned long GetChannelID()const{return m_nChannelID;};
	int  Encode(unsigned char *pdata,int len);
	int	Decode(unsigned char *pdata,int len);
protected:
	unsigned char	m_XX;//udp,tcp,rtp...
	unsigned char	m_Family;
	unsigned short	m_nPort;
	unsigned long	m_IPV4;
	unsigned long	m_nChannelID;
};
class CRelayChannel:public CAttribute{//	0x0001: MAPPED-ADDRESS
public:
	CRelayChannel();
	CRelayChannel(int proto,int family,unsigned long ipv4,unsigned short port,unsigned long rchid,unsigned long chid);
	virtual ~CRelayChannel();
	void SetProto(unsigned char proto){m_XX = proto;};

	void SetFamily(unsigned char family){m_Family = family;};
	void SetPort(unsigned short port){m_nPort = port;};
	void SetIPV4(unsigned long ip){m_IPV4 = ip;};
	void SetChannelID(unsigned long id){m_nChannelID = id;};
	void SetRecvChannelID(unsigned long id){m_nRecvChannelID = id;};
	unsigned char GetProto()const{return m_XX;};
	unsigned char GetFamily()const{return m_Family;};
	unsigned short GetPort()const {return m_nPort;};
	unsigned long GetIPV4()const {return m_IPV4;};
	unsigned long GetChannelID()const{return m_nChannelID;};
	unsigned long GetRecvChannelID()const{return m_nRecvChannelID;};
	int  Encode(unsigned char *pdata,int len);
	int	Decode(unsigned char *pdata,int len);
protected:
	unsigned char	m_XX;//udp,tcp,rtp...
	unsigned char	m_Family;
	unsigned short	m_nPort;
	unsigned long	m_IPV4;
	unsigned long	m_nChannelID;
	unsigned long	m_nRecvChannelID;
};
class CRelayServerID:public CAttribute{//0x0006: USERNAME
public:
	CRelayServerID();
	CRelayServerID(const char *cid){m_nType = MS_ATTRIBUTE_RELAY_SERVER_ID;m_pID = NULL;
	SetRelayServerID(cid);};
	virtual ~CRelayServerID();
	void SetRelayServerID(const char *pcid);
	const char *GetRelayServerID()const{return m_pID;};
	int Encode(unsigned char *pdata,int len);
	int Decode(unsigned char *pdata,int len);
private:
	char*	m_pID;
};

class CChangeRequest:public CAttribute{//0x0003: CHANGE-REQUEST
public:
	CChangeRequest();
	CChangeRequest(unsigned long flag){m_nFlag = flag;m_nType = STUN_ATTRIBUTE_CHANGE_REQUEST;};
	virtual ~CChangeRequest();	
	void SetFlag(unsigned long flag){m_nFlag = flag;};
	unsigned long GetFlag()const{return m_nFlag;};
	int  Encode(unsigned char *pdata,int len);
	int	Decode(unsigned char *pdata,int len);
private:
	unsigned long	m_nFlag;
};
class CSourceAddress:public CMappedAddress{//0x0004: SOURCE-ADDRESS
public:
	CSourceAddress(){m_nType = STUN_ATTRIBUTE_SOURCE_ADDRESS;};
	CSourceAddress(int family,unsigned long ipv4,unsigned short port):CMappedAddress(
		family,ipv4,port){m_nType = STUN_ATTRIBUTE_SOURCE_ADDRESS;};
	#ifdef IPV6_SUPPORT
	CSourceAddress(int family, struct in6_addr & addr6,unsigned short port):CMappedAddress(
		family,addr6,port){m_nType = STUN_ATTRIBUTE_SOURCE_ADDRESS;};
	#endif
	virtual ~CSourceAddress(){};
private:

};
class CChangedAddress:public CAttribute{//	0x0005: CHANGED-ADDRESS
public:
	CChangedAddress();
	CChangedAddress(unsigned char family,unsigned long ip,unsigned short port);
	virtual ~CChangedAddress();
	void SetFamily(unsigned char family){m_Family = family;};
	void SetPort(unsigned short port){m_nPort = port;};
	void SetIPV4(unsigned long ip){m_IPV4 = ip;};
	unsigned char GetFamily(){return m_Family;};
	unsigned short GetPort(){return m_nPort;};
	unsigned long GetIPV4(){return m_IPV4;};

	unsigned char GetFamily()const{return m_Family;};
	unsigned short GetPort()const{return m_nPort;};
	unsigned long GetIPV4()const{return m_IPV4;};

	int  Encode(unsigned char *pdata,int len);
	int	Decode(unsigned char *pdata,int len);
private:
	unsigned char	m_XX;
	unsigned char	m_Family;
	unsigned short	m_nPort;
	unsigned long	m_IPV4;
};
class CUserName:public CAttribute{//0x0006: USERNAME
public:
	CUserName();
	CUserName(const char *pusername){m_nType = STUN_ATTRIBUTE_USERNAME;m_pUserName = NULL;
	SetUserName(pusername);};
	virtual ~CUserName();
	void SetUserName(const char *pname);
	const char *GetUserName()const{return m_pUserName;};
	int Encode(unsigned char *pdata,int len);
	int Decode(unsigned char *pdata,int len);
private:
	char*	m_pUserName;
};
class CPassword:public CAttribute{//	0x0007: PASSWORD
public:
	CPassword();
	CPassword(const char *ppassword){
		m_nType = STUN_ATTRIBUTE_PASSWORD;
	m_pPassword = NULL;SetPassword(ppassword);};
	virtual ~CPassword();
	void SetPassword(const char *ppassword);
	const char *GetPassword()const{return m_pPassword;};
	int Encode(unsigned char *pdata,int len);
	int Decode(unsigned char *pdata,int len);
private:
	char*	m_pPassword;
};
class CChannelID:public CAttribute{//0x0006: USERNAME
public:
	CChannelID();
	CChannelID(const char *cid){m_nType = TURN_ATTRIBUTE_CHANNEL_ID;m_pChannelID = NULL;
	SetChannelID(cid);};
	virtual ~CChannelID();
	void SetChannelID(const char *pcid);
	const char *GetChannelID()const{return m_pChannelID;};
	int Encode(unsigned char *pdata,int len);
	int Decode(unsigned char *pdata,int len);
private:
	char*	m_pChannelID;
};

class CMessageIntegrity:public CAttribute{//0x0008: MESSAGE-INTEGRITY
public:
	CMessageIntegrity();
	CMessageIntegrity(const char *pdigest,int len){m_pDigest = NULL;m_nLength=0;SetData(pdigest,len);m_nType = STUN_ATTRIBUTE_MESSAGE_INTEGRITY;};
	virtual ~CMessageIntegrity();
	int Decode(unsigned char *pdata,int len);
	int Encode(unsigned char *pdata,int len);
	void SetData(const char *pdata,int len);
	const char *GetData()const{return m_pDigest;};
private:
	char*	m_pDigest;
//	int m_nLength;
};
class CErrorCode:public CAttribute{//	0x0009: ERROR-CODE
public:
	CErrorCode();
	CErrorCode(int errorcode);
	virtual ~CErrorCode();
	void SetClass(int c){m_nClass = c;};
	int GetClass(){return m_nClass;};
	void SetNumber(int num){m_nNumber = num;};
	int GetNumber(){return m_nNumber;};
	void SetReason(const char *pres);
	void SetErrorCode(int code);
	int GetErrorCode();
	const char* GetReason(){return m_pReason;};
	int	Encode(unsigned char *pdata,int len);
	int Decode(unsigned char *pdata,int len);
private:
	int		m_nClass;
	int		m_nNumber;
	char*	m_pReason;
};
class CUnknownAttributes:public CAttribute{//	0x000a: UNKNOWN-ATTRIBUTES
public:
	CUnknownAttributes();
	virtual ~CUnknownAttributes();
	const unsigned short *GetAttributes(int &num){num = m_nNumber;return m_pAttributes;};
	void AddAttribute(unsigned short attrib);
	int	Encode(unsigned char *pdata,int len);
	int Decode(unsigned char *pdata,int len);
private:
	unsigned short *m_pAttributes;
	int				m_nNumber;
};
class CReflectedFrom:public CMappedAddress{//	0x000b: REFLECTED-FROM
public:
	CReflectedFrom(){m_nType = STUN_ATTRIBUTE_REFLECTED_FROM;};
	CReflectedFrom(int family,unsigned long ipv4,unsigned short port)
	{	m_nType = STUN_ATTRIBUTE_REFLECTED_FROM;
	m_XX = 0;
	m_Family = family;
	m_nPort = port;
	m_IPV4 = ipv4;};
	virtual ~CReflectedFrom(){};
};

class CLifeTime:public CAttribute{//TURN_ATTRIBUTE_LIFETIME 0x000d
public:
	int	Encode(unsigned char *pdata,int len);
	int Decode(unsigned char *pdata,int len);
	void SetLifeTime(unsigned long lt){m_nLifeTime = lt;};
	unsigned long GetLifeTime(){return m_nLifeTime;};
	unsigned long GetLifeTime()const{return m_nLifeTime;};
	CLifeTime();
	CLifeTime(unsigned long time){	m_nType = TURN_ATTRIBUTE_LIFETIME;
	m_nLifeTime = time;};
	virtual ~CLifeTime();
private:
	unsigned long	m_nLifeTime;
};

class CStartTime:public CAttribute{//TURN_ATTRIBUTE_LIFETIME 0x000d
public:
	int	Encode(unsigned char *pdata,int len);
	int Decode(unsigned char *pdata,int len);
	void SetStartTime(unsigned long lt){m_nStartTime = lt;};
	unsigned long GetStartTime(){return m_nStartTime;};
	unsigned long GetStartTime()const{return m_nStartTime;};
	CStartTime();
	CStartTime(unsigned long time){	m_nType = TURN_ATTRIBUTE_START_TIME;
	m_nStartTime = time;};
	virtual ~CStartTime();
private:
	unsigned long	m_nStartTime;
};

class CStopTime:public CAttribute{//TURN_ATTRIBUTE_LIFETIME 0x000d
public:
	int	Encode(unsigned char *pdata,int len);
	int Decode(unsigned char *pdata,int len);
	void SetStopTime(unsigned long lt){m_nStopTime = lt;};
	unsigned long GetStopTime(){return m_nStopTime;};
	unsigned long GetStopTime()const{return m_nStopTime;};
	CStopTime();
	CStopTime(unsigned long time){	m_nType = TURN_ATTRIBUTE_STOP_TIME;
	m_nStopTime = time;};
	virtual ~CStopTime();
private:
	unsigned long	m_nStopTime;
};


class CAlternateServer:public CMappedAddress{//TURN_ATTRIBUTE_ALTERNATE_SERVER		0x000e
public:
	CAlternateServer(){m_nType = TURN_ATTRIBUTE_ALTERNATE_SERVER;};
	CAlternateServer(int family,unsigned long ipv4,unsigned short port)
	{	m_nType = TURN_ATTRIBUTE_ALTERNATE_SERVER;
	m_XX = 0;
	m_Family = family;
	m_nPort = port;
	m_IPV4 = ipv4;};
	virtual ~CAlternateServer();
};
class CMagicCookie:public CAttribute{//TURN_ATTRIBUTE_MAGIC_COOKIE			0x000f
public:
	int	Encode(unsigned char *pdata,int len);
	int Decode(unsigned char *pdata,int len);
	unsigned long GetMagicCookie(){return m_nMagicCookie;};
	unsigned long GetMagicCookie()const{return m_nMagicCookie;};
	CMagicCookie(){m_nType = TURN_ATTRIBUTE_MAGIC_COOKIE;m_nMagicCookie = 0x72c64bc6;};
	virtual ~CMagicCookie(){};
private:
	unsigned long	m_nMagicCookie;
};

class CBandwidth:public CAttribute{//TURN_ATTRIBUTE_BANDWIDTH 0x0010
public:
	int	Encode(unsigned char *pdata,int len);
	int Decode(unsigned char *pdata,int len);
	void SetLifeTime(unsigned long lt){m_nBandwidth = lt;};
	unsigned long GetBandwidth(){return m_nBandwidth;};
	unsigned long GetBandwidth()const{return m_nBandwidth;};
	CBandwidth();
	CBandwidth(unsigned long bw){	m_nType = TURN_ATTRIBUTE_BANDWIDTH;
	m_nBandwidth = bw;};
	virtual ~CBandwidth();
private:
	unsigned long	m_nBandwidth;
};

class CDestinationAddress:public CMappedAddress{//TURN_ATTRIBUTE_DESTINATION_ADDRESS	0x0011
public:
	CDestinationAddress(){m_nType = TURN_ATTRIBUTE_DESTINATION_ADDRESS;};
	CDestinationAddress(int family,unsigned long ipv4,unsigned short port)
	{	m_nType = TURN_ATTRIBUTE_DESTINATION_ADDRESS;
	m_XX = 0;
	m_Family = family;
	m_nPort = port;
	m_IPV4 = ipv4;};
	virtual ~CDestinationAddress();
};

class CNonce:public CAttribute{//TURN_ATTRIBUTE_NONCE 0x0014
public:
	int	Encode(unsigned char *pdata,int len);
	int Decode(unsigned char *pdata,int len);
	const char *GetNonce(){return m_lpszNonce;};
	const char *GetNonce()const{return m_lpszNonce;};
	void SetNonce(const char *pnonce){if(pnonce && strlen(pnonce) > 0){
		m_lpszNonce = new char[strlen(pnonce)+1];strcpy(m_lpszNonce,pnonce);}else m_lpszNonce = NULL;};
	CNonce(){m_lpszNonce = NULL;m_nType = TURN_ATTRIBUTE_NONCE;};
	CNonce(const char *pnonce){m_lpszNonce = NULL;SetNonce(pnonce); m_nType = TURN_ATTRIBUTE_NONCE;};
	virtual ~CNonce(){if(m_lpszNonce)delete m_lpszNonce;m_lpszNonce = NULL;};
private:
	char*	m_lpszNonce;
};

class CRealm:public CAttribute{//TURN_ATTRIBUTE_REALM 0x0015
public:
	int	Encode(unsigned char *pdata,int len);
	int Decode(unsigned char *pdata,int len);
	const char *GetRealm(){return m_lpszRealm;};
	const char *GetRealm()const{return m_lpszRealm;};
	void SetRealm(const char *prealm){if(prealm && strlen(prealm) > 0){
		m_lpszRealm = new char[strlen(prealm)+1];strcpy(m_lpszRealm,prealm);}else m_lpszRealm = NULL;};
	CRealm(){m_lpszRealm = NULL;m_nType = TURN_ATTRIBUTE_REALM;};
	CRealm(const char *prealm){m_lpszRealm = NULL;SetRealm(prealm);m_nType = TURN_ATTRIBUTE_REALM;};
	virtual ~CRealm(){if(m_lpszRealm)delete m_lpszRealm;m_lpszRealm = NULL;};
private:
	char*	m_lpszRealm;
};

class CData:public CAttribute{//
public:
	int Encode(unsigned char *pdata,int len);
	int Decode(unsigned char *pdata,int len);
	const char *GetData()const{return m_pData;};
	int GetLength()const{return m_nLength;};
	bool SetData(const char *pdata,int len);
	CData();
	CData(const char *pdata,int len);
	virtual ~CData();
private:
	char *m_pData;
};

class CVideowidth:public CAttribute{//TURN_ATTRIBUTE_VIDEO_WIDTH
public:
	int	Encode(unsigned char *pdata,int len);
	int Decode(unsigned char *pdata,int len);	
	unsigned long GetVideowidth(){return m_nVideowidth;};
	unsigned long GetVideowidth()const{return m_nVideowidth;};
	CVideowidth();
	CVideowidth(unsigned long bw){	m_nType = TURN_ATTRIBUTE_VIDEO_WIDTH;
	m_nVideowidth = bw;};
	virtual ~CVideowidth();
private:
	unsigned long	m_nVideowidth;
};

class CVideoheight:public CAttribute{//TURN_ATTRIBUTE_VIDEO_WIDTH
public:
	int	Encode(unsigned char *pdata,int len);
	int Decode(unsigned char *pdata,int len);	
	unsigned long GetVideoheight(){return m_nVideoheight;};
	unsigned long GetVideoheight()const{return m_nVideoheight;};
	CVideoheight();
	CVideoheight(unsigned long bw){	m_nType = TURN_ATTRIBUTE_VIDEO_HEIGHT;
	m_nVideoheight = bw;};
	virtual ~CVideoheight();
private:
	unsigned long	m_nVideoheight;
};

class CVideoformat:public CAttribute{//TURN_ATTRIBUTE_VIDEO_WIDTH
public:
	int	Encode(unsigned char *pdata,int len);
	int Decode(unsigned char *pdata,int len);	
	unsigned long GetVideoformat(){return m_nVideoformat;};
	unsigned long GetVideoformat()const{return m_nVideoformat;};
	CVideoformat();
	CVideoformat(unsigned long bw){	m_nType = TURN_ATTRIBUTE_VIDEO_FORMAT;
	m_nVideoformat = bw;};
	virtual ~CVideoformat();
private:
	unsigned long	m_nVideoformat;
};

class CVideoframerate:public CAttribute{//TURN_ATTRIBUTE_VIDEO_WIDTH
public:
	int	Encode(unsigned char *pdata,int len);
	int Decode(unsigned char *pdata,int len);	
	unsigned long GetVideoframerate(){return m_nVideoframerate;};
	unsigned long GetVideoframerate()const{return m_nVideoframerate;};
	CVideoframerate();
	CVideoframerate(unsigned long bw){	m_nType = TURN_ATTRIBUTE_VIDEO_FRAMERATE;
	m_nVideoframerate = bw;};
	virtual ~CVideoframerate();
private:
	unsigned long	m_nVideoframerate;
};

class CRecordID:public CAttribute{//TURN_ATTRIBUTE_VIDEO_WIDTH
public:
	int	Encode(unsigned char *pdata,int len);
	int Decode(unsigned char *pdata,int len);	
	const char*  GetRecordID(){return m_pRecordID;};
	const char * GetRecordID()const{return m_pRecordID;};
	CRecordID();
	CRecordID(const char* pid){	m_nType = TURN_ATTRIBUTE_RECORD_ID;
	if(pid){m_pRecordID = new char[strlen(pid)+1];strcpy(m_pRecordID,pid);}else{m_pRecordID = NULL;}};
	virtual ~CRecordID();
private:
	char*	m_pRecordID;
};
  
// added by liuhf 2007.10.10

class CPlayScale : public CAttribute{//TURN_ATTRIBUTE_VIDEO_WIDTH
public:
	int	Encode(unsigned char *pdata,int len);
	int Decode(unsigned char *pdata,int len);	
	void SetPlayScale(long scale){	m_nType = TURN_ATTRIBUTE_PLAY_SCALE;
	m_nPlayScale = scale;};
	long GetPlayScale(){return m_nPlayScale;};
	long GetPlayScale()const{return m_nPlayScale;};
	CPlayScale();
	CPlayScale(long scale){	SetPlayScale(scale);};
	virtual ~CPlayScale();
private:
	long	m_nPlayScale;
};


class CPlayType : public CAttribute{//TURN_ATTRIBUTE_VIDEO_WIDTH
public:
	int	Encode(unsigned char *pdata,int len);
	int Decode(unsigned char *pdata,int len);	
	void SetPlayType(const char *ptype);
	const char*  GetPlayType(){return m_pPlayType;};
	const char * GetPlayType()const{return m_pPlayType;};
	CPlayType();
	CPlayType(const char* ptype)
	{	
		m_nType = TURN_ATTRIBUTE_PLAY_TYPE;
		if(ptype)
		{
			m_pPlayType = new char[strlen(ptype)+1];
			strcpy(m_pPlayType,ptype);
		}
		else
		{
			m_pPlayType = NULL;
		}
	};
	virtual ~CPlayType();
private:
	char*	m_pPlayType;
};
  
// added by liuhf 2007.10.10


class COwnerID:public CAttribute{//TURN_ATTRIBUTE_VIDEO_WIDTH
public:
	int	Encode(unsigned char *pdata,int len);
	int Decode(unsigned char *pdata,int len);	
	const char*  GetOwnerID(){return m_pOwnerID;};
	const char * GetOwnerID()const{return m_pOwnerID;};
	COwnerID();
	COwnerID(const char* pid){	m_nType = TURN_ATTRIBUTE_OWNER_ID;
	if(pid){m_pOwnerID = new char[strlen(pid)+1];strcpy(m_pOwnerID,pid);}else{m_pOwnerID = NULL;}};
	virtual ~COwnerID();
private:
	char*	m_pOwnerID;
};

class CSubTitle:public CAttribute{//TURN_ATTRIBUTE_VIDEO_WIDTH
public:
	int	Encode(unsigned char *pdata,int len);
	int Decode(unsigned char *pdata,int len);	
	const char*  GetSubTitle(){return m_pSubTitle;};
	const char * GetSubTitle()const{return m_pSubTitle;};
	CSubTitle();
	CSubTitle(const char* pid){	m_nType = TURN_ATTRIBUTE_SUBTITLE;
	if(pid){m_pSubTitle = new char[strlen(pid)+1];strcpy(m_pSubTitle,pid);}else{m_pSubTitle = NULL;}};
	virtual ~CSubTitle();
private:
	char*	m_pSubTitle;
};



class CSubTitlePos:public CAttribute{//TURN_ATTRIBUTE_VIDEO_WIDTH
public:
	int	Encode(unsigned char *pdata,int len);
	int Decode(unsigned char *pdata,int len);	
	unsigned long GetSubTitlePos(){return m_nSubTitlePos;};
	unsigned long GetSubTitlePos()const{return m_nSubTitlePos;};
	CSubTitlePos();
	CSubTitlePos(unsigned long bw){	m_nType = TURN_ATTRIBUTE_SUBTITLE_POS;
	m_nSubTitlePos = bw;};
	virtual ~CSubTitlePos();
private:
	unsigned long	m_nSubTitlePos;
};


class CTimeTitlePos:public CAttribute{//TURN_ATTRIBUTE_VIDEO_WIDTH
public:
	int	Encode(unsigned char *pdata,int len);
	int Decode(unsigned char *pdata,int len);	
	unsigned long GetTimeTitlePos(){return m_nTimeTitlePos;};
	unsigned long GetTimeTitlePos()const{return m_nTimeTitlePos;};
	CTimeTitlePos();
	CTimeTitlePos(unsigned long bw){	m_nType = TURN_ATTRIBUTE_TIMETITLE_POS;
	m_nTimeTitlePos = bw;};
	virtual ~CTimeTitlePos();
private:
	unsigned long	m_nTimeTitlePos;
};

#ifdef _EHOME_
// 
// Stone Whoo add the following attributes for extension! Refer to design document for detail  
// @20070129

// ATTRIBUTE: USERNAME_ENCRYPTED
class CEncryptedUserName : public CAttribute
{
public:
	CEncryptedUserName()	{ m_nType = MS_ATTRIBUTE_USERNAME_ENCRYPTED; m_pEncryptedUserName = 0; m_nLength = 0;};
	CEncryptedUserName(unsigned char* pdata, int len) {m_nType = MS_ATTRIBUTE_USERNAME_ENCRYPTED; 
														m_pEncryptedUserName = 0; SetUserName(pdata, len);};

	virtual ~CEncryptedUserName()	{ if(m_pEncryptedUserName) delete []m_pEncryptedUserName; };

	void SetUserName(const unsigned char *pname, int len);
	const unsigned char *GetUserName(int& len)const{len = m_nLength; return m_pEncryptedUserName;};	
	int Encode(unsigned char *pdata,int len);	// IN: plain text
	int Decode(unsigned char *pdata,int len);	// OUT: plain text
	
private:
	unsigned char* m_pEncryptedUserName;			// byte stream
};


class CEncryptedPassword : public CAttribute
{
public:
	CEncryptedPassword()	{ m_nType = MS_ATTRIBUTE_PASSWORD_ENCRYPTED; m_pEncryptedPassword = 0; m_nLength = 0;};
	CEncryptedPassword(unsigned char* pdata, int len) { m_nType = MS_ATTRIBUTE_PASSWORD_ENCRYPTED; 
														m_pEncryptedPassword = 0; SetPassword(pdata, len); };

	virtual ~CEncryptedPassword()	{ if(m_pEncryptedPassword) delete []m_pEncryptedPassword; };

	void SetPassword(const unsigned char *ppassword, int len);
	const unsigned char *GetPassword(int& len)const{len = m_nLength; return m_pEncryptedPassword;};	
	int Encode(unsigned char *pdata,int len);	// IN: plain text
	int Decode(unsigned char *pdata,int len);	// OUT:plain text
	
private:
	unsigned char* m_pEncryptedPassword;			// byte stream
};

class CKeepAliveExpire : public CAttribute
{
public:
	CKeepAliveExpire() {m_nType = MS_ATTRIBUTE_KEEPALIVE_VALUE;	m_nExpire = 0; m_nLength = 0; };
	CKeepAliveExpire(unsigned long nExpire){m_nType = MS_ATTRIBUTE_KEEPALIVE_VALUE; SetExpire(nExpire);};

	void SetExpire(int nExpire)	{ m_nExpire = nExpire;	m_nLength = sizeof(m_nExpire); };
	int	GetExpire()const	{	return m_nExpire;	};

	int Encode(unsigned char *pdata,int len);	
	int Decode(unsigned char *pdata,int len);	

private:
	unsigned long m_nExpire;	// unit is s(second).
};

//class CErrorCode is implemented!
class CErrorCode2 : public CErrorCode
{
public:
	CErrorCode2() {	m_nType = MS_ATTRIBUTE_ERROR_CODE; m_nLength = 0; };
	CErrorCode2(uint32 nErrorCode) : CErrorCode(nErrorCode){	m_nType = MS_ATTRIBUTE_ERROR_CODE; SetErrorCode(nErrorCode); m_nLength = sizeof(nErrorCode);};
};

class CMaxConnNum : public CAttribute
{
public:
	CMaxConnNum() {m_nType = MS_ATTRIBUTE_MAX_CONNN_NUM;	m_nMaxConnNum = 0; m_nLength = 0; };
	CMaxConnNum(unsigned long nMaxConn){m_nType = MS_ATTRIBUTE_MAX_CONNN_NUM; SetMaxConnNum(nMaxConn);};

	void SetMaxConnNum(int32 nmaxconn)	{ m_nMaxConnNum = nmaxconn;	m_nLength = sizeof(m_nMaxConnNum); };
	int	GetMaxConnNum()const			{ return m_nMaxConnNum;	};

	int Encode(unsigned char *pdata,int len);	
	int Decode(unsigned char *pdata,int len);	

private:
	unsigned long m_nMaxConnNum;
};


typedef enum
{
	UNKNOWN_PROTO_TYPE = 0,
	TCP_TYPE = 1, 
	UDP_TYPE = 2,
	RTP_TYPE = 3
}PROTOCOL_TYPE;

// CHANNEL_PROTOTYPE
class CProtocolType : public CAttribute
{
public:
	CProtocolType(){ m_nType = MS_ATTRIBUTE_PROTO_TYPE; m_nLength = 0;};//MS_ATTRIBUTE_PROTO_TYPE
	CProtocolType(int32 nProtoType){ m_nType = MS_ATTRIBUTE_PROTO_TYPE; SetProtocolType(nProtoType);};
	~CProtocolType(){};
	
	void SetProtocolType(int nProtoType)	{ m_nProtoType = nProtoType; m_nLength = sizeof(m_nType); };
	int	GetProtocolType()const	{	return m_nProtoType;	};

	int Encode(unsigned char *pdata,int len);	
	int Decode(unsigned char *pdata,int len);	

private:
	int m_nProtoType;
};

/*define a struct*/
// typedef struct __CHANNEL_ID
// {
// 	unsigned long id_MCS;	// every MCS has a unique id in proxy management
// 	unsigned long id_MRS;	// every MRS has a unique id in MCS management
// 	
// 	// MRS allocated unique id for its channels. 8 bytes
//  uint64		id_chann;	// every channel has a unique id in every MRS.
// }CHANNEL_ID;

// MS_ATTRIBUTE_RECV_CHANNEL_ID`
class CRecvChannelID : public CAttribute
{
public:
	CRecvChannelID(){ m_nType = MS_ATTRIBUTE_RECV_CHANNEL_ID; m_nLength = 0; };//MS_ATTRIBUTE_PROTO_TYP
	CRecvChannelID(uint32 chann) { m_nType = MS_ATTRIBUTE_RECV_CHANNEL_ID; SetChannelID(chann); };

	virtual ~CRecvChannelID(){};
	
	void SetChannelID(uint32 chann)	{ m_chann = chann;	m_nLength = sizeof(chann);};
	uint32 GetChannelID()const	{	return m_chann;		};

	int Encode(unsigned char *pdata,int len);	
	int Decode(unsigned char *pdata,int len);	

protected:
	uint32 m_chann;
};

class CTransmitChannelID : public CRecvChannelID
{
public:
	CTransmitChannelID(){ m_nType = MS_ATTRIBUTE_TRANSMIT_CHANNEL_ID; };//MS_ATTRIBUTE_PROTO_TYPE
	CTransmitChannelID(uint32 chann){ m_nType = MS_ATTRIBUTE_TRANSMIT_CHANNEL_ID; SetChannelID(chann);};
	~CTransmitChannelID(){};
};

// MS_ATTRIBUTE_ ADDRESS attribute
class CAllocatedAddress : public CMappedAddress  // 
{
public:
	CAllocatedAddress(){m_nType = MS_ATTRIBUTE_ADDRESS;};
	CAllocatedAddress(int family,unsigned long ipv4,unsigned short port):CMappedAddress(
		family,ipv4,port){m_nType = MS_ATTRIBUTE_ADDRESS;};
	#ifdef IPV6_SUPPORT
	CAllocatedAddress(int family, struct in6_addr& addr6,unsigned short port):CMappedAddress(
		family,addr6,port){m_nType = MS_ATTRIBUTE_ADDRESS;};
	#endif
	virtual ~CAllocatedAddress(){};
private:

};

// MS_ATTRIBUTE_SOURCE_ADDRESS attribute
class CChannSrcAddress : public CMappedAddress
{
public:
	CChannSrcAddress(){m_nType = MS_ATTRIBUTE_SOURCE_ADDRESS;};
	CChannSrcAddress(int family,unsigned long ipv4,unsigned short port):CMappedAddress(
		family,ipv4,port){m_nType = MS_ATTRIBUTE_SOURCE_ADDRESS;};
	#ifdef IPV6_SUPPORT
	CChannSrcAddress(int family, struct in6_addr& addr6,unsigned short port):CMappedAddress(
		family,addr6,port){m_nType = MS_ATTRIBUTE_SOURCE_ADDRESS;};
	#endif
	virtual ~CChannSrcAddress(){};
private:

};

// MS_ATTRIBUTE_DESTINATION_ADDRESS attribute
class CChannDestAddress : public CMappedAddress
{
public:
	CChannDestAddress(){m_nType = MS_ATTRIBUTE_DESTINATION_ADDRESS;};
	CChannDestAddress(int family,unsigned long ipv4,unsigned short port):CMappedAddress(
		family,ipv4,port){m_nType = MS_ATTRIBUTE_DESTINATION_ADDRESS;};
	#ifdef IPV6_SUPPORT
	CChannDestAddress(int family, struct in6_addr& addr6,unsigned short port):CMappedAddress(
		family,addr6,port){m_nType = MS_ATTRIBUTE_DESTINATION_ADDRESS;};
	#endif
	virtual ~CChannDestAddress(){};
private:

};

// MS_ATTRIBUTE_SESSION_ID attribute
class CSessionID : public CAttribute
{
public:
	CSessionID()	{m_nType = MS_ATTRIBUTE_SESSION_ID; m_nLength = 0;};
	CSessionID(std::string& sessionid)	{m_nType = MS_ATTRIBUTE_SESSION_ID; SetSessionID(sessionid);};

	~CSessionID()	{};

	std::string GetSessionID()	{return m_sSessionID;};
	void SetSessionID(std::string& sessionid) /*{m_sSessionID=sessionid; m_nLength = m_sSessionID.size();}*/;
	int  Encode(unsigned char *pdata,int len);
	int	Decode(unsigned char *pdata,int len);

private:
	std::string m_sSessionID;

// 	CSessionID()	{m_nType = MS_ATTRIBUTE_SESSION_ID; m_nSessionID = 0; m_nLength = 0;};
// 	CSessionID(uint32 sessionid)	{m_nType = MS_ATTRIBUTE_SESSION_ID; SetSessionID(sessionid);};
// 
// 	~CSessionID()	{};
// 	uint32 GetSessionID()	{return m_nSessionID;};
// 	void SetSessionID(uint32 sessionid) {m_nSessionID=sessionid; m_nLength = sizeof(m_nSessionID);};
// 	int  Encode(unsigned char *pdata,int len);
// 	int	Decode(unsigned char *pdata,int len);
// 
// private:
// 	uint32 m_nSessionID;
};


// MS_ATTRIBUTE_RECV_PORT_ID attribute
class CRecvPortID : public CAttribute
{
public:
	CRecvPortID() {m_nType = MS_ATTRIBUTE_RECV_PORT_ID; m_nPort = 0; m_nLength = 0;};	// 0 is an invalid port number
	CRecvPortID(int32 nRecvPort) {m_nType = MS_ATTRIBUTE_RECV_PORT_ID; SetPort(nRecvPort);};	

	~CRecvPortID(){};

	int32 GetPort()	{return m_nPort;};
	void SetPort(int32 nRecvPort){m_nPort = nRecvPort; m_nLength = sizeof(m_nPort);};
	int  Encode(unsigned char *pdata,int len);
	int	Decode(unsigned char *pdata,int len);

protected:
	int32 m_nPort;	//	m_nPort is an int32. Its low word part is the port number.
};

// MS_ATTRIBUTE_TRANSMIT_PORT_ID attribute
class CTransmitPortID : public CRecvPortID
{
public:
	CTransmitPortID() {m_nType = MS_ATTRIBUTE_TRANSMIT_PORT_ID; m_nPort = 0;};
	CTransmitPortID(int32 nTransPort) {m_nType = MS_ATTRIBUTE_TRANSMIT_PORT_ID; SetPort(nTransPort);};

	virtual ~CTransmitPortID() {};
};


// complex struct for turn extension
// some related struct
class CRecvChannAttrs
{
public:
	CRecvChannAttrs(CProtocolType* pProtoType, CRecvChannelID* pChannID, 
					CAllocatedAddress* pAllocateAddr, CSessionID* pSessionID, 
					CChannSrcAddress* pSrcAddr);
	CRecvChannAttrs();
	~CRecvChannAttrs();

	// set/get functions
	void SetPrototype(CProtocolType* pProtoType);
	void SetRecvChannID(CRecvChannelID* pChannID);
	void SetAllocatedAddr(CAllocatedAddress* pAllocatedAddr);
	void SetSessionID(CSessionID* pRecvSessionID);
	void SetRecvSrcAddr(CChannSrcAddress* pSrcAddr);

	CProtocolType* GetPrototype()	{return m_pRecvProtoType;};
	CRecvChannelID* GetRecvChannID(){return m_pRecvChannID;};
	CAllocatedAddress* GetAllocatedAddr(){return m_pRecvAllocatedAddr;};
	CSessionID* GetSessionID() {return m_pRecvSessionID;};
	CChannSrcAddress* GetRecvSrcAddr(){return m_pRecvChannSrcAddr;};

	// Param: len is the pdata buffer total length. 
	// Return: attributes total length. That's pdata next attributes starting point to buffer!
	int Encode(unsigned char *pdata,int len);
	// Param: len is the pdata total length. 
	// Return: return m_nLength if ok, else 0. That's pdata next attributes starting point to parse!
	int	Decode(unsigned char *pdata,int len);

private:
	void Clear();	
	bool IsValidRecvChannAttr(uint16 nAttrType);
	
	CProtocolType*		m_pRecvProtoType;
	CRecvChannelID*		m_pRecvChannID;
	CAllocatedAddress*	m_pRecvAllocatedAddr;
	CSessionID*			m_pRecvSessionID;
	CChannSrcAddress*	m_pRecvChannSrcAddr;
};

class CTransChannAttrs
{
public:
	CTransChannAttrs();
	CTransChannAttrs(CProtocolType* pProtoType, CTransmitChannelID* pChannID, 
					CAllocatedAddress* pAllocateAddr, CSessionID* pSessionID, 
					CChannDestAddress* pDestAddr);
	~CTransChannAttrs();

	// set/get functions
	void SetPrototype(CProtocolType* pProtoType);
	void SetTransChannID(CTransmitChannelID* pTransChannID);
	void SetAllocatedAddr(CAllocatedAddress* pAllocatedAddr);
	void SetSessionID(CSessionID* pTransID);
	void SetTransDestAddr(CChannDestAddress* pTransDestAddr);

	CProtocolType* GetPrototype()	{return m_pTransProtoType;};
	CTransmitChannelID* GetTransChannID(){return m_pTransChannID;};
	CAllocatedAddress* GetAllocatedAddr(){return m_pTransAllocatedAddr;};
	CSessionID* GetSessionID() {return m_pTransSessionID;};
	CChannDestAddress* GetTransDestAddr(){return m_pTransChannDestAddr;};

	int Encode(unsigned char *pdata,int len);
	
	int	Decode(unsigned char *pdata,int len);

private:
	void Clear();	

	CProtocolType*		m_pTransProtoType;
	CTransmitChannelID*	m_pTransChannID;
	CAllocatedAddress*	m_pTransAllocatedAddr;
	CSessionID*			m_pTransSessionID;
	CChannDestAddress*	m_pTransChannDestAddr;
};

class CChannAttrsPair
{
public:
	CChannAttrsPair();
	CChannAttrsPair(CRecvChannAttrs* pRecvChannAttrs, CTransChannAttrs* pTransChannAttrs);

	~CChannAttrsPair();

	// encode and decode
	//
	int Encode(unsigned char *pdata,int len);
	int	Decode(unsigned char *pdata,int len);

	void Clear();

	CRecvChannAttrs* GetRecvChannAttrs()	{return m_pRecvChannAttrs;};
	CTransChannAttrs* GetTransChannAttrs()	{return m_pTransChannAttrs;};

	void SetRecvChannAttrs(CRecvChannAttrs* pRecvChannAttrs);	
	void SetTransChannAttrs(CTransChannAttrs* pTransChannAttrs);

private:
	CRecvChannAttrs* m_pRecvChannAttrs;
	CTransChannAttrs* m_pTransChannAttrs;
};

class CRecvPortAttrs
{
public:
	CRecvPortAttrs();
	CRecvPortAttrs(CProtocolType* pProtoType, CRecvPortID* pRecvPort, 
					CAllocatedAddress* pRelayAddr, CSessionID* pSessionID, CChannSrcAddress* pSrcAddr);
	~CRecvPortAttrs();

	// set/get functions
	void SetPrototype(CProtocolType* pProtoType);
	void SetRecvPort(CRecvPortID* pPortID);
	void SetSessionID(CSessionID* pRecvSessionID);
	void SetRecvSrcAddr(CChannSrcAddress* pSrcAddr);
	void SetRecvAddr(CAllocatedAddress* pRecvAddr);
	
	CProtocolType* GetPrototype()	{return m_pProtoType;};
	CRecvPortID* GetRecvPort(){return m_pRecvPort;};
	CSessionID* GetSessionID() {return m_pSessionID;};
	CChannSrcAddress* GetRecvSrcAddr(){return m_pSrcAddr;};
	CAllocatedAddress* GetRecvAddr(){return m_pRecvAddr;}

	int Encode(unsigned char *pdata,int len);

	int	Decode(unsigned char *pdata,int len);

private:
	void Clear();	
	
	CProtocolType*		m_pProtoType;
	CRecvPortID*		m_pRecvPort;
	CSessionID*			m_pSessionID;
	CChannSrcAddress*	m_pSrcAddr;
	CAllocatedAddress*	m_pRecvAddr;
};

class CTransmitPortAttrs
{
public:
	CTransmitPortAttrs();
	CTransmitPortAttrs(CProtocolType* pProtoType, CTransmitPortID* pTransPort, 
						CAllocatedAddress* pRelayAddr, CSessionID* pSessionID, CChannDestAddress* pDestAddr);
	~CTransmitPortAttrs();

	// set/get functions
	void SetPrototype(CProtocolType* pProtoType);
	void SetTransmitPort(CTransmitPortID* pPortID);
	void SetSessionID(CSessionID* pRecvSessionID);
	void SetTransDestAddr(CChannDestAddress* pSrcAddr);
	void SetTransmitAddr(CAllocatedAddress* pTransAddr);

	CProtocolType* GetPrototype()	{return m_pProtoType;};
	CTransmitPortID* GetTransPort(){return m_pTransmitPort;};
	CSessionID* GetSessionID() {return m_pSessionID;};
	CChannDestAddress* GetTransmitDestAddr(){return m_pDestAddr;};
	CAllocatedAddress* GetTransmitAddr(){return m_pTransmitAddr;};

	int Encode(unsigned char *pdata,int len);

	int	Decode(unsigned char *pdata,int len);

private:
	void Clear();	
	
	CProtocolType*		m_pProtoType;
	CTransmitPortID*	m_pTransmitPort;
	CSessionID*			m_pSessionID;
	CChannDestAddress*	m_pDestAddr;
	CAllocatedAddress*	m_pTransmitAddr;
};

class CPortAttrsPair
{
public:
	CPortAttrsPair();
	CPortAttrsPair(CRecvPortAttrs* pRecvPortAttrs, CTransmitPortAttrs* pTransPortAttrs);
	~CPortAttrsPair();

	// encode and decode
	int Encode(unsigned char *pdata, int len);
	int Decode(unsigned char *pdata,int len);
	void Clear();

	void SetTransPortAttrs(CTransmitPortAttrs* pTransPortAttrs);
	void SetRecvPortAttrs(CRecvPortAttrs* pRecvPortAttrs);

	CRecvPortAttrs* GetRecvPortAttrs() {return m_pRecvPortAttrs;};
	CTransmitPortAttrs* GetTransPortAttrs(){return m_pTransPortAttrs;};

private:
	CRecvPortAttrs* m_pRecvPortAttrs;
	CTransmitPortAttrs* m_pTransPortAttrs;
};
#endif
#endif // !defined(AFX_ATTRIBUTE_H__8781445B_8632_45E0_A774_CC1858F14701__INCLUDED_)
